package fr.sedoo.commons.server.news.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import fr.sedoo.commons.client.util.StringUtil;
import fr.sedoo.commons.shared.domain.Message;
import fr.sedoo.commons.shared.domain.message.MessageDTO;
import fr.sedoo.commons.shared.domain.message.TitledMessage;

@Repository
public class MessageDAOJPAImpl implements MessageDAO {

	protected EntityManager em;

	public EntityManager getEntityManager() {
		return em;
	}

	@PersistenceContext
	public void setEntityManager(EntityManager entityManager) {
		this.em = entityManager;
	}

	@Override
	@Transactional
	public ArrayList<Message> findAll() {
		List<Message> aux = em.createQuery("select message from Message message").getResultList();
		ArrayList<Message> result = new ArrayList<Message>();
		result.addAll(aux);
		return result;
	}

	@Transactional
	public Message save(Message message) {
		if (message.getId() == null) {
			getEntityManager().persist(message);
			return message;
		} else {
			getEntityManager().merge(message);
			return message;
		}
	}

	@Override
	@Transactional
	public TitledMessage getConsultMessageContentByUuid(String uuid, String preferredLanguage, List<String> alternateLanguages) {
		String query = "select message from Message as message where message.uuid='" + uuid + "' and message.language='" + preferredLanguage + "'";
		List<Message> aux = em.createQuery(query).getResultList();
		if ((aux.isEmpty()) || (StringUtil.isEmpty(aux.get(0).getTitle())) || (StringUtil.trimToEmpty(aux.get(0).getTitle()).compareToIgnoreCase("<br>") == 0)) {
			if (alternateLanguages.isEmpty() == false) {
				// On va utiliser une nouvelle langue
				String newLanguage = alternateLanguages.get(0);
				alternateLanguages.remove(0);
				return getConsultMessageContentByUuid(uuid, newLanguage, alternateLanguages);
			} else {
				return new TitledMessage();
			}
		} else {
			Message message = aux.get(0);
			return new TitledMessage(message.getTitle(), message.getContent(), message.getAuthor(), message.getDate(), message.getExternaImagelUrl(), message.getIllustrationImageType(),
					message.getUuid());
		}
	}

	@Override
	@Transactional
	public MessageDTO findMessageContentByUuid(String uuid) {

		String illustrationImageType = "";
		String fileName = "";
		String url = "";
		HashMap<String, TitledMessage> contents = new HashMap<String, TitledMessage>();
		String query = "select message from Message as message where message.uuid='" + uuid + "'";
		List<Message> list = em.createQuery(query).getResultList();
		if (list.isEmpty() == false) {
			for (Message message : list) {
				String title = StringUtil.trimToEmpty(message.getTitle());
				String content = StringUtil.trimToEmpty(message.getContent());
				String author = StringUtil.trimToEmpty(message.getAuthor());
				url = message.getExternaImagelUrl();
				illustrationImageType = message.getIllustrationImageType();
				contents.put(message.getLanguage(), new TitledMessage(title, content, author, message.getDate(), url, illustrationImageType, uuid));
			}
		}
		MessageDTO result = new MessageDTO(contents, fileName, illustrationImageType, uuid, url);
		return result;
	}

	@Override
	@Transactional
	public void deleteMessageByUuid(String uuid) {
		List<Message> list = em.createQuery("select message from Message message where message.uuid='" + uuid + "'").getResultList();
		for (Message message : list) {
			em.remove(message);
		}
	}

	@Override
	@Transactional
	public ArrayList<String> getUuids() {

		List<Object[]> aux = em.createQuery("select distinct (message.uuid) , message.date from Message message order by message.date desc ").getResultList();

		ArrayList<String> result = new ArrayList<String>();
		for (Object[] o : aux) {
			result.add((String) o[0]);
		}
		return result;
	}

}